package com.zzwtec.validation.core;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.zzwtec.validation.AnnotationValidator;
import com.zzwtec.validation.ValidateResult;

/**
 * @author  草原狼
 *
 * 2017年8月22日
 */

public class DefaultRuntimeEngine implements ValidatorEngine {
	private static final Logger log = Logger.getLogger(DefaultRuntimeEngine.class.getName());
	
	private final static Map<String,AnnotationValidator> validMaps = new HashMap<String,AnnotationValidator>();
	
	/**
	 * 拷贝验证器集合
	 * @return
	 */
	public Map<String,AnnotationValidator> copyValidMaps(){
		Map<String,AnnotationValidator> validMaps = new HashMap<String,AnnotationValidator>();
		validMaps.putAll(DefaultRuntimeEngine.validMaps);		
		return validMaps;
	}
	/**
	 * 注册解析器
	 * @param parser
	 */
	public void register(String name,AnnotationValidator parser){
		if(! validMaps.containsKey(name)) {
			validMaps.put(name, parser);	
		}	
	}
	
	/**
	 * 支持运行期对该次验证的验证器个数进行调整
	 * @param t
	 * @param skip
	 * @return
	 */
	public <T> ValidateResult validate(T t, RuntimeValidateRule<T> rule) {
		ValidateResult result = null;
		for (Field f : t.getClass().getDeclaredFields()) {
			f.setAccessible(true);
			Object value = null;
			try {
				value = f.get(t);
			} catch (IllegalArgumentException e) {
				log.log(Level.SEVERE, "Exception", e);
			} catch (IllegalAccessException e) {
				log.log(Level.SEVERE, "Exception", e);
			}			
			for (AnnotationValidator va : validMaps.values()) {
				//需要判断是否需要验证--如果匹配排除规则，直接continue				
				if(rule.matchExcludeRule(f.getName(), va.getName())) {
					continue;
				}
				//需要判断是否需要验证--如果匹配包含规则规则，这直接验证
				if(rule.matchCludeRule(f.getName(), va.getName())) {
					result = va.validate(f, value);
				}

				//常规校验
				result = va.validate(f, value);
				
				if(!result.isValid()){
					return result;
				}
			}
		}		
		return result;
	}
	
	
	

	@Override
	public <T> ValidateResult validate(T t) {
		ValidateResult result = null;
		for (Field f : t.getClass().getDeclaredFields()) {
			f.setAccessible(true);
			Object value = null;
			try {
				value = f.get(t);
			} catch (IllegalArgumentException e) {
				log.log(Level.SEVERE, "Exception", e);
			} catch (IllegalAccessException e) {
				log.log(Level.SEVERE, "Exception", e);
			}			
			for (AnnotationValidator va : validMaps.values()) {
				result = va.validate(f, value);			
				if(!result.isValid()){
					return result;
				}
			}
		}
		return result;		
	}

}
